4-4 菢q

JavaScript 的物件可分三類:
  1. 內建的物件(如日期、數學等物件)
  2. 根據網頁的內容所建立的文件物件模型(Document Object Model ,簡稱 DOM)
  3. 使用者自訂的物件
本節將說明「使用者自訂的物件」。若要定義一個簡單物件,擁有數個欄位(或性質),可見下列範例:

Example(object01.htm):

上述範例的原始檔如下:

原始檔(object01.htm):(灰色區域按兩下即可拷貝)
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=big5">
</head>

<body>
<h2 align=center>自訂物件示範:簡單物件</h2>
<hr>

<script src="listProp.js"></script>
<script>
student = new Object();
student.name = "Timmy";
student.age = "25";
student.phone = "575-1114";
listProp(student, "student");
</script>

<hr>
</body>
</html>

在上述範例中,我們使用 new Object() 來產生一個使用者自訂的物件,並設立此物件的三個性質,分別是 name, age, 以及 phone。此外,我們用到了一個函數 listProp() 來印出物件的所有性質,此函數是經有下列敘述來加入此網頁:

<script src="listProp.js"></script> 此函數的內容如下:

原始檔(listProp.js):(灰色區域按兩下即可拷貝)
// 列印物件性質
function listProp(obj, objName) {
	for (var i in obj)
		document.writeln(objName+".<font color=red>"+i+"</font> = <font color=green>"+obj[i]+"</font><br>");
}

我們也可以使用「單列指定」的方式,來指定一個物件的所有性質,其格式如下:

newObj = {prop1:value1, prop2:value2, ...}; 若使用此種方式來指定一個物件,上述範例可以改寫如下:

原始檔(object02.htm):(灰色區域按兩下即可拷貝)
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=big5">
</head>

<body>
<h2 align=center>自訂物件示範:簡單物件</h2>
<hr>

<script src="listProp.js"></script>
<script>
student = {"name":"Timmy", "age":25, "phone":"575-1114"}
listProp(student, "student");
</script>

<hr>
</body>
</html>

Hint
使用此種「單列指定」的好處是:可以指定含有空格的性質,但是若要存取此(含有空格的)性質,則必須使用「物件["性質"]」的方式來進行,而不能使用「物件.性質」的方式。

若要測試一個物件是否含有某個特定欄位,可以使用 in 運算子,例如:

Example(in01.htm):

上述範例的原始檔如下:

原始檔(in01.htm):(灰色區域按兩下即可拷貝)
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=big5">
</head>

<body>
<h2 align=center>以 in 運算子測試物件的欄位是否存在</h2>
<hr>

<script src="listProp.js"></script>
<script>
student = new Object();
student.name = "Timmy";
student.age = "25";
student.phone = "575-1114";
field = "age";
if (field in student)
	document.write(field + " is a field of student<br>");
</script>

<hr>
</body>
</html>

若要產生較複雜的自訂物件,包含定義此物件的性質和方法,首先就要定義此物件的「建構子」(Constructor,也就是用來創造物件的函數),其形式和一般 JavaScript 的函數非常類似。以下是一個簡單的範例:

Example(object03.htm):

上述範例的原始檔如下:

原始檔(object03.htm):(灰色區域按兩下即可拷貝)
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=big5">
</head>

<body>
<h2 align=center>自訂物件示範:較複雜物件</h2>
<hr>

<script>
function student(inputName, inputStudentID, inputAge) {
	this.name = inputName;
	this.studentID = inputStudentID;
	this.age = inputAge;
	this.display = displayStudent;
}

function displayStudent() {
	var outStr="大名 = "+this.name+"\n";
	outStr = outStr + "學號 = "+this.studentID+"\n";
	outStr = outStr + "年齡 = "+this.age;
	alert(outStr);
}

student1 = new student("Alex",695326,23);
student2 = new student("Joey",998735,20);
student3 = new student("Kelvin",978732,22);
</script>

按鈕以顯示學生資訊:
<form>
<input type=button value=student1 onClick="javascript:student1.display()">
<input type=button value=student2 onClick="javascript:student2.display()">
<input type=button value=student3 onClick="javascript:student3.display()">
</form>

<hr>
</body>
</html>

其中,我們利用函數 student 來定義一個物件範本,包含了三個性質:name、studentID、及 age。此外,此物件範本也包含了一個方法 display(),是由另一個函數 displayStudent() 所定義。在這兩個函數中,「this」代表所建構的物件。

此外,物件中亦可包含另一個物件,例如:

Example(object04.htm):

上述範例的原始檔如下:

原始檔(object04.htm):(灰色區域按兩下即可拷貝)
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=big5">
</head>

<body>
<h2 align=center>自訂物件示範:巢狀式物件</h2>
<hr>

<script>
function course(inputName, inputCourseID, inputCredit) {
	this.name = inputName;
	this.courseID = inputCourseID;
	this.credit = inputCredit;
	this.display = displayCourse;
}

function displayCourse() {
	var outStr="名稱 = "+this.name+"\n";
	outStr = outStr + "課號 = "+this.courseID+"\n";
	outStr = outStr + "學分 = "+this.credit+"\n";
	alert(outStr);
}

function student(inputName, inputStudentID, inputAge, inputCourse) {
	this.name = inputName;
	this.studentID = inputStudentID;
	this.age = inputAge;
	this.course = inputCourse;
	this.display = displayStudent;
}

function displayStudent() {
	var outStr="大名 = "+this.name+"\n";
	outStr = outStr + "學號 = "+this.studentID+"\n";
	outStr = outStr + "年齡 = "+this.age+"\n";
	outStr = outStr + "課程 = "+this.course.name+"\n";
	alert(outStr);
}

course1 = new course("Web 程式設計、技術與應用","CS3431",3);
course2 = new course("音訊處理與辨識","CS5770",3);
course3 = new course("離散數學","CS3111",2);
student1 = new student("Alex", 695326, 23, course1);
student2 = new student("Joey", 998735, 20, course2);
student3 = new student("Kelvin", 978732, 22, course1);
</script>

按鈕以顯示課程或學生資訊:
<form>
課程:
<input type=button value=course1 onClick="javascript:course1.display()">
<input type=button value=course2 onClick="javascript:course2.display()">
<input type=button value=course3 onClick="javascript:course3.display()">
<br>
學生:
<input type=button value=student1 onClick="javascript:student1.display()">
<input type=button value=student2 onClick="javascript:student2.display()">
<input type=button value=student3 onClick="javascript:student3.display()">
</form>

<hr>
</body>
</html>

其中我們使用 course() 和 student() 來建構「課程」和「學生」的物件,而「學生」物件中的 course 性質,則是指向由 course() 所產生的「課程」物件。

當物件的個數較多時,我們通常是將每一個物件放在陣列中,以便存取與管理。在下列的範例中,我們以陣列來存放每個月的開支列表,而每一筆經費本身就是一個物件,包含此經費的金額、說明等,因此,我們可以很方便地加入一筆開銷記錄,並列印出整體支出表,範例如下:

Example(expenseTable.htm):

上述範例的原始檔如下:

原始檔(expenseTable.htm):(灰色區域按兩下即可拷貝)
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=big5">
</head>

<body>
<h2 align=center>自訂物件示範:以陣列來存放支出表</h2>
<hr>

<script>
function expenseItem(expense, timeUnit, multiply, comment) {
	this.expense = expense;
	this.timeUnit=timeUnit;
	this.multiply = multiply;
	this.comment = comment;
}
// 列出每一項支出名目
expense = new Array();
i=0;
expense[i++]=new expenseItem( 200, "每天", 365/12, "餐費");
expense[i++]=new expenseItem(3000, "每月", 1, "房租");
expense[i++]=new expenseItem(1000, "每月", 1, "電費+瓦斯+水費+電話");
expense[i++]=new expenseItem( 500, "每週", 365/12/7, "購物及其他雜費");
expense[i++]=new expenseItem( 300, "每週", 365/12/7, "交通費");
// 列印支出表
document.writeln("<table align=center border=1>")
document.writeln("<tr><th>說明<th>單價<th>時間單位<th>乘數<th>每月小計")
total=0;
for (i=0; i<expense.length; i++){
	document.writeln("<tr>");
	document.writeln("<td align=center>"+expense[i].comment);
	document.writeln("<td align=right>"+expense[i].expense);
	document.writeln("<td align=center>"+expense[i].timeUnit);
	document.writeln("<td align=right>"+expense[i].multiply);
	document.writeln("<td align=right>"+Math.round(expense[i].expense*expense[i].multiply));
	total=total+expense[i].expense*expense[i].multiply;
}
document.writeln("<tr><td colspan=4>&nbsp;<td align=right><b>每月總計</b>:"+Math.round(total));
document.writeln("</table>")
</script>

<hr>
</body>
</html>


JavaScript 程式設計與應用:用於網頁用戶端